package com.whfc.openapi.api.face.service;

import com.whfc.common.constant.QueueConst;
import com.whfc.common.file.FileHandler;
import com.whfc.common.file.FilePathConfig;
import com.whfc.common.util.Base64Util;
import com.whfc.common.util.DateUtil;
import com.whfc.common.util.JSONUtil;
import com.whfc.common.util.RandomUtil;
import com.whfc.emp.dto.AppFaceGateDTO;
import com.whfc.emp.dto.AppFaceGatePersonDTO;
import com.whfc.emp.dto.AppFaceGateVisitorDTO;
import com.whfc.emp.enums.EmpSyncImgType;
import com.whfc.emp.enums.FaceGateType;
import com.whfc.emp.enums.NetState;
import com.whfc.emp.param.*;
import com.whfc.emp.service.AppFaceGateService;
import com.whfc.emp.service.AppFaceGateVisitorService;
import com.whfc.openapi.redis.FaceGateAttendRedisDao;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author qzexing
 * @version 1.0
 * @date 2021-08-05 16:13
 */
@Service
public class FaceGateSyncServiceImpl implements FaceGateSyncService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @DubboReference(interfaceClass = AppFaceGateService.class, version = "1.0.0")
    private AppFaceGateService appFaceGateService;

    @DubboReference(interfaceClass = AppFaceGateVisitorService.class, version = "1.0.0")
    private AppFaceGateVisitorService appFaceGateVisitorService;

    @Autowired
    FaceGateAttendRedisDao faceGateAttendRedisDao;

    @Autowired
    private FilePathConfig filePathConfig;

    @Autowired
    private FileHandler fileHandler;

    @Autowired
    private AmqpTemplate amqpTemplate;

    /**
     * 同一个人同一个闸机刷脸时间间隔大于1分钟
     */
    private static final Integer INTERVAL_TIME = 1;

    @Override
    public void syncAttend(EmpAttendSyncDataParam dataParam) {
        if (dataParam == null) {
            return;
        }
        // (1)验证闸机-唯一标识
        String deviceKey = dataParam.getDeviceKey();
        if (StringUtils.isBlank(deviceKey)) {
            logger.warn("考勤记录同步, deviceKey为空, param:{}", dataParam);
            return;
        }
        AppFaceGateDTO faceGate = appFaceGateService.getByDeviceKey(deviceKey);
        if (faceGate == null) {
            logger.warn("考勤记录同步-闸机未入后台数据库, deviceKey:{} ", deviceKey);
            return;
        }
        // (2)验证时间-过滤重复记录
        String personGuid = dataParam.getPersonGuid();
        Date time = dataParam.getShowTime();
        //从缓存中获取上一次打卡记录
        Date latestShowTime = faceGateAttendRedisDao.getShowTime(deviceKey, personGuid);
        if (latestShowTime != null && DateUtil.addMinutes(latestShowTime, INTERVAL_TIME).after(time)) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            logger.info("两次刷脸时间相同, time:{}, latestShowTime:{}", sdf.format(time), sdf.format(latestShowTime));
            return;
        }
        //保存刷脸时间到缓存中
        faceGateAttendRedisDao.setShowTime(deviceKey, personGuid, time);

        Integer deptId = faceGate.getDeptId();

        //在线闸机需要验证闸机授权状态
        String platform = dataParam.getPlatform();
        FaceGateType faceGateType = FaceGateType.parseCode(platform);
        Integer empId = null;
        if (NetState.ONLINE.getValue().equals(faceGateType.getState())) {
            // 查找授权人员
            AppFaceGatePersonDTO faceGatePerson = appFaceGateService.getByDeviceKeyAndGuid(deviceKey, personGuid);
            if (faceGatePerson != null) {
                empId = faceGatePerson.getEmpId();
            }else {
                AppFaceGateVisitorDTO gateVisitorDTO = appFaceGateVisitorService.getByDeviceKeyAndGuid(deviceKey, personGuid);
                if (gateVisitorDTO == null) {
                    logger.info("人员未授权,deptId:{}, personGuid:{}, deviceKey:{}", deptId, personGuid, deviceKey);
                    return;
                }else {
                    dataParam.setEmpName(gateVisitorDTO.getName());
                }
            }

        }

        dataParam.setDeptId(deptId);
        dataParam.setFaceGateId(faceGate.getFaceGateId());
        if (dataParam.getDirection()==null) {
            dataParam.setDirection(faceGate.getDirection());
        }
        dataParam.setEmpId(empId);
        //上传图片
        setAttendImgUrl(dataParam);
        //推送消息
        String jsonStr = JSONUtil.toString(dataParam);
        amqpTemplate.convertAndSend(QueueConst.EMP_FACEGATE_ATTEND_DATA, jsonStr);
        //麦管家闸机需要同步至湖南监管平台
        if (FaceGateType.WHEATSUNSHINE.getCode().equals(dataParam.getPlatform())) {
            // 实名制考勤同步放入队列
            // 处理识别后待处理的数据放入队列
            FaceGateDataParam faceGateData = new FaceGateDataParam();
            faceGateData.setPicture(dataParam.getPicture());
            faceGateData.setDeviceKey(deviceKey);
            faceGateData.setDirection(faceGate.getDirection());
            faceGateData.setName(faceGate.getName());
            faceGateData.setTime(dataParam.getShowTime());
            faceGateData.setEmpId(empId);
            faceGateData.setProjectId(deptId);
            amqpTemplate.convertAndSend(QueueConst.ATTEND_SYNC_HUNAN_EXC, "", JSONUtil.toString(faceGateData));
        }
    }


    @Override
    public void syncEmpInfo(EmpInfoSyncDataParam dataParam) {
        if (dataParam == null) {
            return;
        }
        //推送消息
        String jsonStr = JSONUtil.toString(dataParam);
        amqpTemplate.convertAndSend(QueueConst.EMP_FACEGATE_EMP_INFO, jsonStr);
    }

    @Override
    public void syncGroup(EmpGroupSyncDataParam dataParam) {
        if (dataParam == null) {
            return;
        }
        //推送消息
        String jsonStr = JSONUtil.toString(dataParam);
        amqpTemplate.convertAndSend(QueueConst.EMP_FACEGATE_GROUP_DATA, jsonStr);
    }


    @Override
    public void syncDevice(EmpDeviceSyncDataParam dataParam) {
        if (dataParam == null) {
            return;
        }
        //推送消息
        String jsonStr = JSONUtil.toString(dataParam);
        amqpTemplate.convertAndSend(QueueConst.EMP_FACEGATE_DEVICE_DATA, jsonStr);
    }

    /**
     * 获取考勤识别图片
     *
     * @param dataParam 识别数据
     */
    private void setAttendImgUrl(EmpAttendSyncDataParam dataParam) {
        Integer imgType = dataParam.getImgType();
        if (null == imgType) {
            return;
        }
        String ossPath = "emp/faceGateRecord";
        if (EmpSyncImgType.BASE64.getValue().equals(imgType)) {
            String img = uploadImg(dataParam.getPicture(), ossPath);
            dataParam.setPicture(img);
        }
    }


    /**
     * 上传识别照片
     *
     * @param base64Str base64
     * @return 图片地址
     */
    private String uploadImg(String base64Str, String ossPath) {
        String imgUrl = "";
        if (StringUtils.isEmpty(base64Str)) {
            return imgUrl;
        }
        try {
            byte[] imageByte = Base64Util.decode(base64Str);
            ByteArrayInputStream inputStream = new ByteArrayInputStream(imageByte);
            String path = filePathConfig.getFilePath(ossPath, RandomUtil.getRandomFileName(), "Jpeg");
            imgUrl = fileHandler.upload(path, inputStream, "30d");
        } catch (Exception e) {
            logger.warn("考勤识别上传base64图片失败", e);
        }
        return imgUrl;
    }

}
